package hapi.flash.util;

#if flash9
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
typedef AnimationBase = Bitmap;
#else
import flash.display.BitmapData;
import flash.MovieClip;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
#end

class AnimationCache {
	
	var animations:Hash<Array<BitmapData>>;
	
	public function new(){
		animations = new Hash<Array<BitmapData>>();
	}
	
	public function get(id):CashedAnimation {
		var animation = animations.get(id);
		var animation = new CashedAnimation(animations.get(id));
		animation.play();
		return animation;
	}
	
	public function add(id):Void {
		if(!animations.exists(id)){
			animations.set(id,buildCacheFromLibrary(id));
		}
	}
	
	function buildCacheFromLibrary(id):Array<BitmapData> {
		#if flash9
		var tmp = flash.Lib.attach(id);
		var frames = buildCacheFromClip(tmp);
		#else
		var d = flash.Lib.current.getNextHighestDepth();
		var tmp = flash.Lib.current.attachMovie(id,"___tmp___"+d,d,{_x:-10000,_visible:false});
		var frames = buildCacheFromClip(tmp);
		tmp.removeMovieClip();
		#end
		return frames;
	}
	
	function buildCacheFromClip(clip:MovieClip):Array<BitmapData> {
		var frames = new Array<BitmapData>();
		#if flash9
		var r = clip.getRect(clip);
		#else
		var bounds = clip.getRect(clip);
		var r = new Rectangle(bounds.xMin, bounds.yMin, Math.abs(bounds.xMax-bounds.xMin), Math.abs(bounds.xMax-bounds.xMin));
		#end
		
		for (i in 1...(clip.totalFrames+1)){
			clip.gotoAndStop(i);
			var bitmapData:BitmapData = new BitmapData(Std.int(r.width), Std.int(r.height), true, 0x00000000);
			var m:Matrix = new Matrix();
			m.translate(-r.x, -r.y);
			m.scale(clip.scaleX, clip.scaleY);
			bitmapData.draw(clip,m);
			frames.push(bitmapData);
		}
		return frames;
	}
}

#if flash9
class CashedAnimation extends AnimationBase {
#else
class CashedAnimation {
#end
	
	var clip:MovieClip;
	var frames:Array<BitmapData>;
	public var currentFrame:Int;
	
	public var totalFrames(getTotalFrame,null):Int;
	
	public function new(frames) {
		#if flash9
		super();
		#end
		this.frames = frames;
		currentFrame  =1;
	}
	
	public function play() {
		gotoAndStop(currentFrame);
		#if flash9
		addEventListener(Event.ENTER_FRAME, enterFrame);
		#else
		#end
	}
	
	public function stop() {
		gotoAndStop(currentFrame);
		#if flash9
		removeEventListener(Event.ENTER_FRAME, enterFrame);
		#else
		#end
	}
	
	public function gotoAndStop(frame:Int){
		currentFrame = Math.round(frame);
		render();
	}
	
	public function gotoAndPlay(frame:Int){
		gotoAndStop(frame);
		play();
	}
	
	#if flash9
	public function enterFrame(e:Event){
		currentFrame++;
		if (currentFrame > totalFrames) currentFrame = 1;
		gotoAndStop(currentFrame);
	}
	#end
	
	function getTotalFrame(){
		return frames.length;
	}
	
	function render(){
		#if flash9
		bitmapData = frames[currentFrame - 1];
		#else
		#end
	}
}